package com.example.Holo.uiactivities.fragments.expensefragment;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.example.Holo.R;
import com.example.Holo.library.viewfinder.IViewFinder;
import com.example.Holo.rework.core.Friend;
import com.example.Holo.uiactivities.components.NumberPicker;
import com.example.Holo.uiactivities.fragments.BaseFragment;
import com.example.Holo.utils.functions.IIn;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import static android.content.Context.LAYOUT_INFLATER_SERVICE;
import static android.text.InputType.TYPE_CLASS_NUMBER;
import static com.example.Holo.library.viewfinder.ViewFinders.getViewFinder;
import static com.example.Holo.uiactivities.components.NumberPicker.IRun;

public class NewExpenseFragment extends BaseFragment implements Observer {

    public final List<FriendsPayment> friendPayments = new ArrayList<FriendsPayment>();
    private ArrayAdapter<FriendsPayment> adapter;
    private ArrayAdapter<FriendsPayment> quantityAdapter;

    private MvcView mvcView;
    public final MvcModel mvcModel = new MvcModel();

    private final static String FOR_WHAT_KEY = "forWhat";
    private final static String HOW_MUCH_KEY = "howMuch";

    @Override
    public String getFragmentTitle() {
        return "Expenses";
    }

    @Override
    public int getActivityMenuResource() {
        return R.menu.new_expenses_fragment_menu;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.expenses_fragment, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final IViewFinder viewFinder = getViewFinder(activity);
        mvcView = new MvcView(viewFinder);
        mvcModel.addObserver(this);
        adapter = new ArrayAdapter<FriendsPayment>(activity, android.R.layout.simple_list_item_1, friendPayments);
        mvcView.spinner.setAdapter(adapter);
        mvcView.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                final FriendsPayment friendsPayment = friendPayments.get(position);
                mvcModel.setPaidFriendId(friendsPayment.friend.id);
                mvcModel.setPaidFriendName(friendsPayment.friend.name);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        mvcView.spinner.setSelection(0);
        final ListView listView = viewFinder.findListView(R.id.friend_payments);
        final View view = LayoutInflater.from(getActivity().getApplicationContext()).inflate(R.layout.expenses_friends_listview_header, null);
        listView.addHeaderView(view, null, false);
        final LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(LAYOUT_INFLATER_SERVICE);
        quantityAdapter = new ArrayAdapter<FriendsPayment>(activity, android.R.layout.simple_list_item_1, friendPayments) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                final FriendInfo viewHolder;
                if (convertView == null) {
                    convertView = layoutInflater.inflate(R.layout.expenses_friend_quantity, parent, false);
                    viewHolder = new FriendInfo();
                    viewHolder.init(convertView);
                    convertView.setTag(viewHolder);
                } else {
                    viewHolder = (FriendInfo) convertView.getTag();
                }
                final FriendsPayment friend = friendPayments.get(position);
                viewHolder.provideValues(friend, parent);
                return convertView;
            }
        };
        listView.setAdapter(quantityAdapter);
        tryToRestoreBundle(savedInstanceState);
        initMvcViewEvents();
        initFriendsList();
    }

    @Override
    public void onFragmentIsOnFocus() {
        initFriendsList();
    }

    private void initMvcViewEvents() {
        final DialogFragment dialog = new DatePickerFragment();
        mvcView.datePicker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.show(activity.getSupportFragmentManager(), "datePicker");
            }
        });
        mvcView.totalPayment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showInputQuantityDialog(new IIn<String>() {
                    @Override
                    public void in(String enteredValue) {
                        final Double enteredQuantity = new Double(enteredValue);
                        mvcModel.setPaymentQuantity(enteredQuantity);
                        mvcModel.informObserver();
                    }
                });
            }
        });
        mvcView.forWhatElement.addTextChangedListener(new TextChangeListener() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                mvcModel.setForWhat(s.toString());
            }
        });
    }

    private void tryToRestoreBundle(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            mvcModel.setPaymentQuantity(savedInstanceState.getDouble(HOW_MUCH_KEY));
            mvcModel.setForWhat(savedInstanceState.getString(FOR_WHAT_KEY));
        }
        mvcModel.informObserver();
    }

    private void showInputQuantityDialog(final IIn<String> in) {
        final EditText input = new EditText(this.activity);
        input.setInputType(TYPE_CLASS_NUMBER);
        final AlertDialog.Builder alert = new AlertDialog.Builder(this.activity)
                .setTitle("Enter quantity:")
                .setView(input)
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        in.in(input.getText().toString());
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
        alert.show();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(FOR_WHAT_KEY, mvcModel.getForWhat());
        outState.putDouble(HOW_MUCH_KEY, mvcModel.getPaymentQuantity());
        mvcModel.informObserver();
    }

    @Override
    public void update(Observable observable, Object data) {
        mvcView.forWhatElement.setText(mvcModel.getForWhat());
        mvcView.totalPayment.setText(getDecimalFormat(mvcModel.getPaymentQuantity()));
    }

    private String getDecimalFormat(double quantity) {
        final String pattern = quantity == 0 ? "0.00" : "#.00";
        final DecimalFormat dec = new DecimalFormat(pattern);
        return dec.format(quantity);
    }

    class FriendInfo {

        private TextView name;
        private NumberPicker numberOfItems;
        private TextView quantity;

        public void init(View view) {
            final IViewFinder viewFinder = getViewFinder(view);
            name = viewFinder.findTextView(R.id.friend_name);
            numberOfItems = (NumberPicker) view.findViewById(R.id.np_pieces);
            quantity = (TextView) view.findViewById(R.id.friend_payment);
        }

        private void calculatePieces(ViewGroup parent) {
            for (int i = 0; i <= quantityAdapter.getCount(); i++) {
                if (i > 0) {
                    final View element = parent.getChildAt(i);
                    final FriendsPayment friendsPayment = friendPayments.get(i - 1);
                    final double piece = (mvcModel.getPaymentQuantity() - getHandEnteredQuantity()) / getNumberOfPaymentsWithoutByHand();
                    final int quant = friendsPayment.getPiecesCount();
                    final TextView view = (TextView) element.findViewById(R.id.friend_payment);
                    if (quant > 0 && !friendsPayment.isEnteredByHand()) {
                        final double enteredQuantity = piece * quant;
                        friendsPayment.setQuantity(enteredQuantity);
                        final String credits = getDecimalFormat(enteredQuantity);
                        if (view != null) {
                            view.setText(credits);
                        }
                    } else {
                        if (view != null) {
                            if (friendsPayment.isEnteredByHand()) {
                                view.setText(getDecimalFormat(friendsPayment.getQuantity()));
                            } else {
                                view.setText(getDecimalFormat(0));
                            }
                        }
                    }
                }
            }
        }

        private int getNumberOfPaymentsWithoutByHand() {
            int sum = 0;
            for (FriendsPayment friendsPayment : friendPayments) {
                if (!friendsPayment.isEnteredByHand()) {
                    sum += friendsPayment.getPiecesCount();
                }
            }
            return sum;
        }

        private double getHandEnteredQuantity() {
            double sum = 0;
            for (FriendsPayment friendsPayment : friendPayments) {
                if (friendsPayment.isEnteredByHand()) {
                    sum += friendsPayment.getQuantity();
                }
            }
            return sum;
        }

        public void provideValues(final FriendsPayment friendsPayment, final ViewGroup parent) {
            name.setText(friendsPayment.friend.name);
            numberOfItems.setValue(friendsPayment.getPiecesCount());
            numberOfItems.setFocusable(true);
            numberOfItems.setFocusableInTouchMode(true);
            numberOfItems.handlePlusButtonClick(new IRun<Integer>() {
                @Override
                public void run(Integer value) {
                    friendsPayment.setPiecesCount(value);
                    calculatePieces(parent);
                }
            });
            numberOfItems.handleMinusButtonClick(new IRun<Integer>() {
                @Override
                public void run(Integer value) {
                    if (value > 0) {
                        friendsPayment.setPiecesCount(value);
                        calculatePieces(parent);
                    } else {
                        friendsPayment.setEnteredByHand(false);
                    }
                }
            });
            numberOfItems.handleAnyValueSetChanged(new IRun<Integer>() {
                @Override
                public void run(Integer value) {
                    friendsPayment.setPiecesCount(value);
                    calculatePieces(parent);
                }
            });
            quantity.setText(getDecimalFormat(friendsPayment.getQuantity()));
            quantity.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showInputQuantityDialog(new IIn<String>() {
                        @Override
                        public void in(String enteredValue) {
                            friendsPayment.setQuantity(Double.valueOf(enteredValue));
                            friendsPayment.setEnteredByHand(true);
                            if (friendsPayment.getPiecesCount() == 0) {
                                numberOfItems.increment.performClick();
                            }
                            calculatePieces(parent);
                        }
                    });
                }
            });
        }

    }

    public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final LayoutInflater lo = getActivity().getLayoutInflater();
            final View view = lo.inflate(R.layout.date_picker_component, null);
            final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setView(view);
            return builder.create();
        }

        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

        }

    }

    private void initFriendsList() {
        friendPayments.clear();
        for (Friend friend : data.friends) {
            friendPayments.add(new FriendsPayment(friend));
        }
        adapter.notifyDataSetChanged();
    }

}
